﻿using System.Globalization;
using System.Linq;
using Fuse8.DomainFramework.BusinessService;
using Fuse8.DomainFramework.Common.Locator;
using Fuse8.DomainFramework.DataAccess.InMemoryDatabase;
using Fuse8.GlobalizationFramework.BusinessServices;
using Fuse8.GlobalizationFramework.Domain;
using Fuse8.GlobalizationFramework.Domain.Commands;
using Fuse8.GlobalizationFramework.Infrastructure;
using Microsoft.Practices.Unity;
using Moq;
using NUnit.Framework;

namespace UnitTests
{
    [TestFixture]
    public class GlobalizableBusinessServiceTests
    {
        private BusinessServiceFacade<Resource, int> businessServiceFacade;
        private Mock<IGlobalizationSetting> settings;
        private UnityContainer container;

        [SetUp]
        public void SetUp()
        {
            container = new UnityContainer();
            var locator = new UnityServiceLocatorWithLazy(container);
            DependencyServiceLocator.SetLocatorProvider(() => locator);

            var entityDataRepository = InMemoryDataRepositoryConfiguration<Resource, int>.CreateRepository();
            entityDataRepository.Add(new Resource()
            {
                Key = "Key1",
                Value = "Value1",
                Locale = "fr-FR"
            });
            entityDataRepository.Add(new Resource()
            {
                Key = "Key2",
                Value = "Value2",
                Locale = "fr-FR"
            });
            entityDataRepository.Add(new Resource()
            {
                Key = "Key1",
                Value = "en1",
                Locale = "en-GB"
            });
            entityDataRepository.Add(new Resource()
            {
                Key = "Key2",
                Value = "en2",
                Locale = "en-GB"
            });
            entityDataRepository.Add(new Resource()
            {
                Key = "Key3",
                Value = "en3",
                Locale = "en-GB"
            });
            container.RegisterInstance(entityDataRepository);
            var factory = new Mock<IResourceCommandFactory>();
            factory.Setup(p => p.GetCommand<ResourceSelectAllByLocale>()).Returns(
                new ResourceSelectAllByLocaleInMemoryCommand());

            settings = new Mock<IGlobalizationSetting>();            
            settings.Setup(p => p.DefaultCulture).Returns(new CultureInfo("en-GB"));
            container.RegisterInstance(factory.Object);
            container.RegisterInstance<IEntityBusinessService<Resource, int>>(new GlobalizableBusinessService<Resource>());
            businessServiceFacade = new BusinessServiceFacade<Resource, int>();
        }

        [Test]
        public void Add_NewResourceItem_AddsInCurrentLanguage()
        {
            settings.Setup(p => p.CurrentCulture).Returns(new CultureInfo("fr-FR"));
            container.RegisterInstance(settings.Object);

            var item = new Resource() {Key = "test 1", Value = "test 2"};            
            businessServiceFacade.Add(item);
            Assert.AreEqual("fr-FR", item.Locale);
        }

        [Test]
        public void Add_EditInDefaultCulture_SavesInDefault()
        {
            settings.Setup(p => p.CurrentCulture).Returns(new CultureInfo("en-GB"));
            container.RegisterInstance(settings.Object);

            var item = AdminResourceService.FindAll().FirstOrDefault(p => p.Key == "Key1");
            item.Value = "new value";
            businessServiceFacade.Save(item);
            Assert.AreEqual("en-GB", item.Locale);
            Assert.AreEqual("new value", item.Value);
        }

        [Test]
        public void Add_EditExistingResourceInNotDefaultCulture_SavesInDefault()
        {
            settings.Setup(p => p.CurrentCulture).Returns(new CultureInfo("fr-FR"));
            container.RegisterInstance(settings.Object);

            var item = AdminResourceService.FindAll().FirstOrDefault(p => p.Key == "Key1");
            item.Value = "new value";
            businessServiceFacade.Save(item);
            Assert.AreEqual("fr-FR", item.Locale);
            Assert.AreEqual("new value", item.Value);
        }

        [Test]
        public void Add_EditNotExistingResourceInNotDefaultCulture_SavesInDefault()
        {
            settings.Setup(p => p.CurrentCulture).Returns(new CultureInfo("fr-FR"));
            container.RegisterInstance(settings.Object);

            var item = AdminResourceService.FindAll().FirstOrDefault(p => p.Key == "Key3");
            item.Value = "new value";
            businessServiceFacade.Save(item);
            Assert.AreEqual("fr-FR", item.Locale);
            Assert.AreEqual("new value", item.Value);
        } 
    }
}
